﻿using System;
using System.Collections.Generic;
using System.Text;
using Sinacor.Infra.Common.Exceptions;
using Sinacor.Infra.Service.ExceptionHandling;
using System.Collections;
using Sinacor.Servico.Bovespa.Ordens;
using Sinacor.Infra.Service.Common;

namespace Sinacor.Servico.Bovespa.Ordens.BusinessLogic
{
    public class LoteOrdem : BaseBusinessLogic
    {
        #region Constantes de Erro
        private const int ERRO_IMPOSSIVELCRIARLOTE = 109893;// O cliente informado não foi encontrado.
        #endregion

        /// <summary>
        /// Logica de inclusao de LoteOrdem
        /// </summary>
        /// <param name="ordem"
        /// <returns>bool : Ordem Criada com Sucesso</returns>
        // 14/07/2008       Marcelo Barucci      Criacao
        // 01/10/2008 16:30 WAbreu.7COMm         Revisao
        public int CriarLoteOrdem(List<BusinessEntity.LoteOrdem> pListLoteOrdem)
        {
            if (pListLoteOrdem == null || pListLoteOrdem.Count == 0)
                return 0;

            List<BusinessEntity.LoteOrdem> lListLoteOrdem = new List<Sinacor.Servico.Bovespa.Ordens.BusinessEntity.LoteOrdem>();
            ResourceAccess.LoteOrdem loteOrdemRA = new ResourceAccess.LoteOrdem();
            ResourceAccess.Negocio negocio = new ResourceAccess.Negocio();

            /* Verificar se alguma ordem da lista já esta em algum lote.
               Caso esteja em um lote já existente, então apenas para a primeira ocorrencia 
               encontrada utilizar o metodo CriarLoteOrdemComLote.
               Para o resto da lista deve-se utilizar o Metodo TrocarOrdemLote e passar o resto das ordens.
            */
            foreach (BusinessEntity.LoteOrdem item in pListLoteOrdem)
            {
                BusinessLogic.Negocio validarEstadoSistema = new Negocio();
                validarEstadoSistema.ValidarEstadoSistema(Sinacor.Servico.Bovespa.Ordens.BusinessEntity.Enum.ModuloChamador.ControleOrdens);

                if (item.NumeroConjunto.HasValue && item.NumeroConjunto != 0)
                {
                    // cria um novo lote e envia a ordem para dentro dele. remove essa ordem da lista.
                    int numeroLoteAux = loteOrdemRA.CriarLoteOrdemComLote(item);                  
                    pListLoteOrdem.Remove(item);

                    // se ainda houver itens na lista depois de criado o lote, envia-os
                    // para dentro do lote recem-criado.
                    if (pListLoteOrdem.Count > 0)
                        loteOrdemRA.TrocarOrdemLote(pListLoteOrdem, numeroLoteAux);                    

                    // devolve numero do novo lote
                    return numeroLoteAux;
                }

                BusinessEntity.Parameter.ConsultarNegocioOrdemDigitacaoRequest pConsultarNegocioOrdemDigitacao = new BusinessEntity.Parameter.ConsultarNegocioOrdemDigitacaoRequest();
                pConsultarNegocioOrdemDigitacao.DataOrdem = item.DataOrdem;
                pConsultarNegocioOrdemDigitacao.DataPregao = item.DataPregao;
                pConsultarNegocioOrdemDigitacao.NumeroOrdem = item.NumeroSequenciaOrdem;
                pConsultarNegocioOrdemDigitacao.NumeroOrdemSubSequencia = item.NumeroSubSequenciaOrdem;
                List<BusinessEntity.Negocio> listneg = negocio.ConsultarNegocioOrdemDigitacao(pConsultarNegocioOrdemDigitacao);

                if (listneg != null && listneg.Count > 0)
                {
                    lListLoteOrdem.Add(item);
                }

            }

            /* Caso nenhuma ordem da lista esteja vinculada a um lote ja existente, 
               então deve-se chamar o metodo CriarLoteOrdemSemLote. 
            */

            if (lListLoteOrdem.Count == 0)
                throw new BusinessException(ERRO_IMPOSSIVELCRIARLOTE);

            return loteOrdemRA.CriarLoteOrdemSemLote(lListLoteOrdem);
        }

        /// <summary>
        /// Descricao : Logica de troca Ordem de Lote
        /// Autor : Marcelo Barucci
        /// Data : 14/07/2008
        /// </summary>
        /// <param name="ordem"
        /// <returns>bool operação executada com sucesso</returns>
        public bool TrocarLoteOrdem(List<BusinessEntity.LoteOrdem> pListLoteOrdem, Int32 numeroLoteDestino)
        {
            //VERIFICA SE O SISTEMA ESTÁ ABERTO ANTES DE REALIZAR A TROCA DE ORDENS
            BusinessLogic.Negocio validarEstadoSistema = new Negocio();
            validarEstadoSistema.ValidarEstadoSistema(Sinacor.Servico.Bovespa.Ordens.BusinessEntity.Enum.ModuloChamador.ControleOrdens);

            if (numeroLoteDestino > 0)
                return new ResourceAccess.LoteOrdem().TrocarOrdemLote(pListLoteOrdem, numeroLoteDestino);
            else
                return new ResourceAccess.LoteOrdem().TrocarOrdemLote(pListLoteOrdem);
        }

        /// <summary>
        /// Descricao : Logica de troca Ordem de Lote
        /// Autor : Marcelo Barucci
        /// Data : 14/07/2008
        /// </summary>
        /// <param name="ordem"
        /// <returns>bool operação executada com sucesso</returns>
        public bool TrocarLoteOrdem(List<BusinessEntity.LoteOrdem> pListLoteOrdem)
        {
            if (pListLoteOrdem == null || pListLoteOrdem.Count < 1)
                return false;

            return TrocarLoteOrdem(
                pListLoteOrdem, 
                pListLoteOrdem[0].NumeroConjuntoDestino == null ? 0 : (int)pListLoteOrdem[0].NumeroConjuntoDestino
            );
        }

        /// <summary>
        /// Autor : WAbreu.7COMm
        /// Data : 17/07/2008
        /// </summary>
        /// <param name="pRequest"> objeto ConsultarLoteVinculadoParameter contendo os valores </param>
        /// <returns>Lista de LoteOrdem</returns>               
        /// WAbreu.7COMM  2008-10-13 16:46  "Novo Lote" torna-se responsabilidade da camada de UI.
        public List<BusinessEntity.LoteOrdem> ConsultarLoteVinculado(BusinessEntity.Parameter.ConsultarLoteVinculadoParameter pRequest)
        {
            //pRequest.CodigoNegocio = ((pRequest.CodigoNegocio.Substring(pRequest.CodigoNegocio.Trim().Length - 1, 1) == "Q") ? pRequest.CodigoNegocio.Substring(1, pRequest.CodigoNegocio.Trim().Length - 2) : pRequest.CodigoNegocio);
            return (new ResourceAccess.LoteOrdem()).ConsultarLoteVinculado(pRequest);

            #region WAbreu.7COMM  2008-10-13 16:46  DESATIVADO. Responsabilidade da UI.
            // BusinessEntity.LoteOrdem beLoteOrdemAtual = null;
            // List<BusinessEntity.LoteOrdem> listLoteOrdemResult = new List<BusinessEntity.LoteOrdem>();

            // obter lista
            // List<BusinessEntity.LoteOrdem> listLoteOrdem = (new ResourceAccess.LoteOrdem()).ConsultarLoteVinculado(pRequest);
            
            //if (listLoteOrdem != null && listLoteOrdem.Count != 0)
            //{
            //    // percorrer a lista
            //    foreach (BusinessEntity.LoteOrdem lo in listLoteOrdem)
            //    {
            //        // encontrar o lote atual para inserir como primeiro item da lista
            //        if (lo.NumeroConjunto == pRequest.NumeroConjunto)
            //        {
            //            beLoteOrdemAtual = lo;
            //            break;
            //        }
            //    }

            //    // se nao encontrou o lote atual, gerar Exception
            //    if (beLoteOrdemAtual == null)
            //        throw new BusinessException(0);

            //    // o primeiro item da lista sera´ o lote atual (encontrado anteriormente)
            //    listLoteOrdemResult.Add(beLoteOrdemAtual);

            //    // inserir uma copia do lote atual com nome de "Novo Lote"
            //    BusinessEntity.LoteOrdem loNovo = new BusinessEntity.LoteOrdem();
            //    loNovo.NomeLote = "Novo Lote";
            //    loNovo.NumeroConjunto = beLoteOrdemAtual.NumeroConjunto;
            //    loNovo.PrecoMedio = beLoteOrdemAtual.PrecoMedio;
            //    listLoteOrdemResult.Add(loNovo);

            //    // inserir os demais elementos na lista APOS os dois anteriores
            //    foreach (BusinessEntity.LoteOrdem lo in listLoteOrdem)
            //    {
            //        if (lo.NumeroConjunto == pRequest.NumeroConjunto)
            //            continue;

            //        listLoteOrdemResult.Add(lo);
            //    }
            //}

            // return listLoteOrdemResult;   
            #endregion WAbreu.7COMM  2008-10-13 16:46  DESATIVADO. Responsabilidade da UI.
        }
    }
}
